import { defineComponent, markRaw, reactive, watch } from 'vue'
import DataNode from '../../ItemNode/DataNode'
import {
  ElButton,
  ElIcon,
  ElImage,
  ElInput,
  ElRadioButton,
  ElRadioGroup,
  ElSwitch,
  ElText
} from 'element-plus'
import classes from '../../ItemNode/ItemNode.module.css'
import { Picture } from '@element-plus/icons-vue'
import { uploadFile, file2Base64 } from '../../utils'
import { staticUrl } from '../../request/request'
import Tip from '../../panel/Tip.vue'

export default class NImage extends DataNode {
  isNImage = true
  isDataDisplayNode = true
  styleDisplay = 'inline-block'

  constructor(node?: NImage) {
    super(node)

    if (!node) {
      this.path = './components/NImage/NImage.tsx'
      this.name = '图片'

      this.props.style = {
        ...this.props.style,
        display: this.styleDisplay,
        maxWidth: '100%',
        minWidth: '10px',
        minHeight: '10px'
      }

      this.props.dataFnable = false
      this.props.src = ''
      this.props.fit = 'fill'
      this.props.lazy = false // 绝对定位且lazy为true，图片会不显示
      this.props.preview = false
    }

    const fitOptions = reactive([
      {
        label: '等比包含',
        value: 'contain'
      },
      {
        label: '等比裁剪',
        value: 'cover'
      },
      {
        label: '填充',
        value: 'fill'
      },
      {
        label: '无',
        value: 'none'
      }
    ])

    const pComponent = this.component
    this.component = markRaw(
      defineComponent(
        (props) => {
          watch(
            () => this.props.data,
            () => {
              if (this.props.dataFnable) this.props.src = this.props.data ?? ''
            },
            { immediate: true }
          )

          return () => (
            <pComponent>
              <ElImage
                style={{
                  width: '100%',
                  height: '100%',
                  minWidth: '30px',
                  minHeight: '30px'
                }}
                src={staticUrl(this.props.src)}
                fit={this.props.fit}
                lazy={this.props.lazy}
                previewSrcList={this.props.preview ? [staticUrl(this.props.src)] : null}
              >
                {{
                  error: () => (
                    <div
                      style={{
                        display: 'flex',
                        justifyContent: 'center',
                        alignItems: 'center',
                        width: '100%',
                        height: '100%'
                      }}
                    >
                      <ElIcon size={30} color="var(--el-text-color-regular)">
                        <Picture />
                      </ElIcon>
                    </div>
                  )
                }}
              </ElImage>
            </pComponent>
          )
        },
        {
          name: 'NImage'
        }
      )
    )

    const pView = this.view
    this.view = markRaw(
      defineComponent((props) => {
        return () => (
          <pView>
            <this.component style={{ width: '100px', transform: 'scale(0.8)' }}></this.component>
          </pView>
        )
      })
    )

    const pParams = this.params
    this.params = markRaw(
      defineComponent(() => {
        return () => (
          <pParams>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                图片地址
              </ElText>
              <div class={classes['params-item-content']}>
                <ElInput v-model={this.props.src} size="small" clearable></ElInput>
                <ElButton
                  type="primary"
                  size="small"
                  onClick={() => {
                    uploadFile((file) => {
                      file2Base64(file).then((res) => (this.props.src = res))
                    })
                  }}
                >
                  选择图片
                </ElButton>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                图片适应
              </ElText>
              <div class={classes['params-item-content']}>
                <ElRadioGroup v-model={this.props.fit} size="small">
                  {() =>
                    fitOptions.map((item) => (
                      <ElRadioButton
                        key={item.value}
                        label={item.label}
                        value={item.value}
                      ></ElRadioButton>
                    ))
                  }
                </ElRadioGroup>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                懒加载
                <Tip content="绝对定位且懒加载为true，图片会不显示"></Tip>
              </ElText>
              <div class={classes['params-item-content']}>
                <ElSwitch v-model={this.props.lazy} size="small"></ElSwitch>
              </div>
            </div>
            <div class={classes['params-item']}>
              <ElText class={classes['params-item-label']} type="info">
                图片预览
              </ElText>
              <div class={classes['params-item-content']}>
                <ElSwitch v-model={this.props.preview} size="small"></ElSwitch>
              </div>
            </div>
          </pParams>
        )
      })
    )
  }

  toVue(): SfcObj {
    const sfcObj = super.toVue()

    sfcObj.imports = {
      ...sfcObj.imports,
      'element-plus': {
        ElImage: 'ElImage',
        ElIcon: 'ElIcon'
      },
      ['@element-plus/icons-vue']: {
        Picture: 'Picture'
      }
    }

    sfcObj.template = sfcObj.template.replace(
      '<slot></slot>',
      `
  <ElImage
    :style="{
      width: '100%',
      height: '100%',
      minWidth: '30px',
      minHeight: '30px'
    }"
    src="${this.props.src}"
    fit="${this.props.fit}"
    :lazy="${this.props.lazy}"
    :previewSrcList="${this.props.preview ? `['${this.props.src}']` : null}"
  >
    <template #error>
      <ElIcon :size="30" color="var(--el-text-color-regular)">
        <Picture />
      </ElIcon>
    </template>
  </ElImage>
      `
    )

    return sfcObj
  }
}
